【AWS】EC2をリソースレベルでアクセス許可してみた
はじめに
こんにちは植木和樹です。2013年7月9日に「EC2とRDSをリソースレベルでアクセス制限する機能」が発表されましたので、さっそく使ってみました。
【AWS発表】EC2とRDSのリソースにリソースレベルのアクセス許可を設定可能に
この機能を聞いて最初に思いついたのが、学校の授業などでAWSを使うケースです。生徒ごとに専用EC2やRDSインスタンスを割り当て、自分所有のインスタンス以外は停止・破棄できないように制限するという使い方です。学校の授業や会社のオペトレ時のように「利用者ごとにAWSアカウントを分けることは難しいけれど、利用者がお互いのリソースに干渉するのは防ぎたい」というシチュエーションには便利な機能ではないでしょうか。
ちなみにクラスメソッドでは、開発環境と本番環境はAWSアカウントレベルで区別することを推奨しているため「開発者に本番環境を操作させたくない・・・」といったシチュエーションは少ないかもです。
IAMを用いたリソースのアクセス制限
IAMによるリソース制限を簡単にまとめると次のような制限が可能です。
人/動作/リソース | 設定対象 | 設定例 |
---|---|---|
誰が | IAMユーザ または IAMグループ | iam-user-A iam-admin-group |
何に | リソース または 条件 | arn:aws:ec2:ap-northeast-1:123456789012:instance/i-12345678 タグ: Name=WebServer |
どのような操作ができるか | アクション | ec2:StartInstances ec2:describe* |
実際に確認してみる
EC2インスタンスの作成
まずはEC2インスタンスを2つ用意しましょう。t1.micro でまったく同じ構成です。起動後分かりやすいように名前(Name)をつけておきましょう。
IAMユーザの作成
作成した2台のEC2インスタンス(node-A,node-B)をそれぞれ専有する2人のユーザ(iam-user-A、iam-user-B)を作成しましょう。2ユーザの権限は次のように設定したいと思います。
ユーザ | 対象リソース | 可能な操作 |
---|---|---|
ユーザA、ユーザB | すべてのEC2 | 情報の表示 |
ユーザA | EC2: node-A | EC2の起動、停止、リブート |
ユーザB | EC2: node-B | EC2の起動、停止、リブート、ターミネイト |
まずはマネージメントコンソールのIAMのページで2つのユーザを作成します。
マネージメントコンソールにログインできるようパスワードも設定しておきましょう。
次にユーザAのポリシーを設定します。
カスタムポリシーで下記JSONをテキストエリアに貼り付けて"Apply Policy"します。Resourceで arn を指定することで node-A のみをStartInstance/RebootInstance/StopInstance 操作できます。arnの"123456789012"はAWSアカウントIDです。("::"でアカウントID省略記法が使えるか試したのですが、省略はできないようです)
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "ec2:describe*" ], "Sid": "Stmt1373379895000", "Resource": [ "*" ], "Effect": "Allow" }, { "Action": [ "ec2:StartInstances", "ec2:RebootInstances", "ec2:StopInstances" ], "Sid": "Stmt1373378552000", "Resource": [ "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-54440856" ], "Effect": "Allow" } ] }
ユーザBについては次のポリシーを設定します。こちらは arn ではなく、タグ(Name=node-B)でリソースを指定しています。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "ec2:describe*" ], "Sid": "Stmt1373379896000", "Resource": [ "*" ], "Effect": "Allow" }, { "Action": [ "ec2:RebootInstances", "ec2:StartInstances", "ec2:StopInstances", "ec2:TerminateInstances" ], "Sid": "Stmt1373381303000", "Condition": { "StringEquals": { "ec2:ResourceTag/Name": "node-B" } }, "Resource": [ "*" ], "Effect": "Allow" } ] }
なおIAMのポリシーJSONを作成するときは「Policy Generator」を使って生成されるJSONを確認しながら進めると楽です。
マネージメントコンソールからEC2を操作する
マネージメントコンソールでユーザA、ユーザBそれぞれでログインし、ここまでに設定してきたアクセスが可能か確認してみましょう。
まず ユーザA でログインします。
ユーザAは node-A の起動、停止、リブートはできますがターミネイトはできません。
またユーザAは node-B については情報をみる以外、一切操作できません。
次に ユーザB でログインします。ユーザBは node-B の起動、停止、リブートができ、ターミネイトもできます。node-A については情報をみる以外、一切操作できません。
インスタンスを両方同時に停止しようとしても操作ができません。
まとめ
今回はEC2のARNとEC2のタグで指定したリソースに対してアクセス制限を行なってみました。発表ではRDSもリソース単位の制限がかけられるようになったそうなので機会をみて試してみたいです。
またIAMを用いたリソースレベルのアクセス制限は、条件(Condition)によってより高度な制限がかけられるようになっています(条件については今回タグ名でリソースを指定するのに使用しています)。例えば "StringEquals" : { "ec2Region" : "ap-northeast-1" } と指定することでTokyoリージョン以外ではEC2インスタンスを起動できなくしたり、ec2InstanceTypeで m1.small 以外のインスタンスタイプを使えなくしたりすることも(CreateInstanceアクションが設定対象になれば将来的には)できそうです。(指定できる条件のリスト)
授業中生徒に「時間あたり460ドルのコストを払って、ハイストレージ・エイトエクストララージ(hs1.8xlarge) を100台起動!」なんてことをされないよう、必要に応じてアクセス制限はかけておきたいものです。